﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Data.SqlServerCe;
using System.Data;
using OverStore.Configuration;
using System.Collections.ObjectModel;
using OverStore.TutorialAsTest.UnitTest.Configuration.Rdbms.InstanceStorage;
using OverStore.Configuration.Components;
using OverStore.Configuration.Storage;
using OverStore.Sql.TableSchema;
using System.Reflection;
using OverStore.Configuration.ObjectRepository;
using OverStore.Configuration.ObjectRepository.CommandSet;
using OverStore.Configuration.ObjectRepository.Reader;

namespace OverStore.TutorialAsTest.UnitTest.Configuration.Rdbms.ObjectReader
{
    [TestClass]
    public class SimpleClassReader_Test
    {
        public AdoNetStorageConfiguration<SqlCeConnection> CreateDataSource(string connectionString)
        {
            return new AdoNetStorageConfiguration<SqlCeConnection>
                {
                    ConnectionString = connectionString
                };
        }

        public OverStoreConfiguration CreateConfiguration(string connectionString)
        {
            var config = new OverStoreConfiguration();
            config.DataStorage = CreateDataSource(connectionString);

            config.AddRepository(CreateSimpleClassObjectRepositoryConfig());
            return config;
        }

        public PersistenceObjectRepositoryConfiguration<SimpleClass, Guid> CreateSimpleClassObjectRepositoryConfig()
        {
            TableCommandSetConfiguration storageConfig = new TableCommandSetConfiguration()
            {
                TableSchema = new Table
                {
                    Name = "SimpleClass",
                    Columns = new ColumnBase[] 
                    {
                        new Key<Guid>       { Name = "ID" },
                        new Column<string>  { Name = "Name" },
                        new Column<DateTime>{ Name = "CreationDate" },
                        new Column<int>     { Name = "Type" }
                    }
                }
            };

            var mapper = Component.Mapper.Delegate<SimpleClass>((item, name, p) =>
                                            {
                                                switch (name)
                                                {
                                                    case "ID":
                                                        return item.ID;
                                                    case "Name":
                                                        return item.Name;
                                                    case "CreationDate":
                                                        return item.CreationDate;
                                                    case "Type":
                                                        return item.Type;
                                                    case "orig__ID":
                                                        return p.GetIdentifier<SimpleClass, Guid>(item);
                                                    default:
                                                        return Missing.Value;
                                                }
                                            },
                                            (data, item, p) =>
                                            {
                                                item.ID = data.GetGuid("ID");
                                                item.Name = data.GetString("Name");
                                                item.CreationDate = data.GetDateTime("CreationDate");
                                                item.Type = (SimpleClassType)data.GetInt32("Type");
                                            });

            return new PersistenceObjectRepositoryConfiguration<SimpleClass, Guid>()
            {
                ChangesTracker = Component.InstanceChangesTracker.Checksum<SimpleClass, Guid>("ID", "Name", "CreationDate", "Type"),
                Commands = storageConfig,
                Depot = Component.Depot.WithInternalKey<SimpleClass, Guid>("Id"),
                Mapper = mapper,
                ParameterlessReader = new ParameterlessReaderConfiguration<SimpleClass, Guid>
                {
                    IdentifierProvider = Component.IdentifierProvider.Delegate<Guid>(r => r.GetGuid("ID")),
                    UseResultSetForObjectConstruction = false,
                    ReadCommand = new AdoNetCommandConfiguration
                    {
                        Sql = "SELECT ID FROM SimpleClass"
                    }
                }
            };
        }

        private static List<Guid> IdSet = new List<Guid>()
        {
           new Guid("508538e3-111b-4fde-a714-20fb78205662"),
           new Guid("f30c02ce-33fd-4dda-8228-500609c8ee7b"),
           new Guid("64ca46ee-de9e-4388-9a79-96f1a062fc52"),
           new Guid("8f10f298-b4a3-4686-ab7e-e565f8bee70a")
        };

        [TestMethod]
        public void ObjectReader_IntegralTest()
        {
            var connectionString = TestHelper.CreateTestDbCopyAndBuildConnectionString();
            int i = 0;
            using (var session = CreateConfiguration(connectionString).CreateSession())
            {
                foreach (var simpleClass in session.CreateReader<SimpleClass>())
                {
                    Assert.IsTrue(IdSet.Contains(simpleClass.ID));
                    Assert.AreSame(session.GetByIdentifier<SimpleClass, Guid>(simpleClass.ID), simpleClass);
                    i++;
                }
            }
        }

    }
}
